package org.tinaelle.client.utils;

import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.user.client.ui.HasHorizontalAlignment.HorizontalAlignmentConstant;

public class Table extends FlexTable {

	public class AddRow {

		public final HorizontalAlignmentConstant	CENTER	= HasHorizontalAlignment.ALIGN_CENTER;

		private int		                         column;

		public final HorizontalAlignmentConstant	LEFT	= HasHorizontalAlignment.ALIGN_LEFT;

		public final HorizontalAlignmentConstant	RIGHT	= HasHorizontalAlignment.ALIGN_RIGHT;

		private final int		                 row;

		public AddRow() {
			row = getRowCount();
			column = 0;
		}

		public AddRow(final int itemsAfter) {
			row = insertRow( getRowCount() - itemsAfter );
			column = 0;
		}

		public Cell add(final Currency val) {
			return add( val.toString() ).setHAlign( RIGHT );
		}

		public Cell add(final float val) {
			return add( String.valueOf( val ) ).setHAlign( RIGHT );
		}

		public Cell add(float val, final int precision, final String unit) {
			// what is an elegant way of formating floats in GWT as
			// String.format() doesn't exist??
			int f = 10;
			for ( int i = 1; i < precision; i++ ) {
				f *= 10;
			}
			val *= f;
			val = ( int ) val;
			val /= f;
			final Cell c = add( val + " " + unit );
			return c.setHAlign( RIGHT );
		}

		public Cell add(final float val, final String unit) {
			return add( val, 2, unit );
		}

		public Cell add(final int val) {
			return add( String.valueOf( val ) ).setHAlign( RIGHT );
		}

		public Cell add(final int val, final String unit) {
			return add( val + " " + unit ).setHAlign( RIGHT );
		}

		public Cell add(final String text) {
			setText( row, column, text );
			return new Cell( row, column++ );
		}

		public Cell add(final Widget widget) {
			setWidget( row, column, widget );
			return new Cell( row, column++ );
		}

		public int addC(final String text) {
			setHAlign( HasHorizontalAlignment.ALIGN_CENTER );
			setText( row, column, text );
			return column++;
		}

		public Cell addHtml(final String html) {
			setHTML( row, column, html );
			return new Cell( row, column++ );
		}

		public int addHtmlC(final String html) {
			setHAlign( HasHorizontalAlignment.ALIGN_CENTER );
			setHTML( row, column, html );
			return column++;
		}

		public int addHtmlR(final String html) {
			setHAlign( HasHorizontalAlignment.ALIGN_RIGHT );
			setHTML( row, column, html );
			return column++;
		}

		public int addWidgetC(final Widget widget) {
			setWidget( row, column, widget );
			setHAlign( HasHorizontalAlignment.ALIGN_CENTER );
			return column++;
		}

		public int addWidgetR(final Widget widget) {
			setWidget( row, column, widget );
			setHAlign( HasHorizontalAlignment.ALIGN_RIGHT );
			return column++;
		}

		public int getRow() {
			return row;
		}

		private void setHAlign(final HorizontalAlignmentConstant align) {
			getCellFormatter().setHorizontalAlignment( row, column, align );
		}
	}

	public class Cell {
		private final int	column;

		private final int	row;

		public Cell(final int row, final int column) {
			super();
			this.row = row;
			this.column = column;
		}

		public Cell bold() {
			setHTML( row, column, "<b>" + getHTML( row, column ) + "</b>" );
			return this;
		}

		public Cell setColspan(final int val) {
			getFlexCellFormatter().setColSpan( row, column, val );
			return this;
		}

		public Cell setHAlign(final HorizontalAlignmentConstant align) {
			getFlexCellFormatter().setHorizontalAlignment( row, column, align );
			return this;
		}

		public Cell setRowspan(final int val) {
			getFlexCellFormatter().setRowSpan( row, column, val );
			return this;
		}
	}

	public AddRow addRow() {
		return new AddRow();
	}

	public AddRow addRow(final int itemsAfter) {
		return new AddRow( itemsAfter );
	}

	public void truncateToSize(final int size) {
		for ( int i = getRowCount() - 1; i >= size; i-- ) {
			removeRow( i );
		}
	}

}
